package cn.hg.jfsa.common;

import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.IAtom;
import com.jfinal.plugin.activerecord.Model;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class LogManager implements Runnable {

	private static final LogManager me = new LogManager();

	public static LogManager me() {
		return me;
	}

	private static Thread THREAD;
	/**
	 * 私有代构造方法，不允许创建
	 */
	private LogManager(){}

	private Log	log = Log.getLog(LogManager.class);

	private boolean isLogEnabled = false;

	private int logLimit = 20;

	private long logTime = 1 * 60 * 1000L;

	private List<Model< ? >> logActionList = new ArrayList<>();

	public void add(Model< ? > log) {
		if (!this.isLogEnabled) return;

		synchronized (logActionList) {
			logActionList.add(log);
		}
		// 如果缓存数量大于限制数量，则写数据库
		if (logActionList.size() >= this.logLimit) {
			this.flush();
		}
	}

	public void flush() {
		synchronized (logActionList) {
			if (logActionList.size() == 0) return;

			// 启动数据库线程
			Db.tx(new IAtom() {
				@Override
				public boolean run() throws SQLException {
					if(logActionList.size() == 0) return true;
					log.debug("写日志到数据库。。。");
					for (Model<?> log : logActionList) {
						log.save();
					}
					logActionList.clear();
					return true;
				}
			});
		}
	}

	public void setLogEnabled(boolean logEnabled) {
		isLogEnabled = logEnabled;
		if (this.isLogEnabled) {
			THREAD = new Thread(this);
			THREAD.start();
		} else {
			THREAD.interrupt();
			THREAD = null;
		}
	}

	/**
	 * 设置日志缓存数
	 * @param limit
	 */
	public void setLogLimit(int limit){
		this.logLimit = limit;
	}

	public void setLogTime(int time){
		this.logTime = time * 60 * 1000;
	}

	@Override
	public void run() {
		while (true) {
			try {
				Thread.sleep(this.logTime);
				if (this.isLogEnabled) {
					this.flush();
				}
			} catch (InterruptedException e) {
				log.warn("日志管理器线程错误：", e);
			}
		}
	}

	public boolean isLogEnabled() {
		return isLogEnabled;
	}

	public int getLogLimit() {
		return logLimit;
	}

	public long getLogTime() {
		return logTime;
	}
}
